Skip to main content

Overview

The Orchestrator class is the main backend entry point for the CS2 Market Tracker. It coordinates all schedulers with shared rate limiting, ensuring all components work in harmony without exceeding Steam’s API rate limits. Think of it as a choir conductor - it ensures all parts (schedulers) work together while respecting API constraints.

Class Definition

from cerebro import Orchestrator

orchestrator = Orchestrator(config_path="config.yaml")

Constructor

config_path
str
default:"config.yaml"
Path to YAML configuration file

Attributes

config
dict | None
Loaded configuration from YAML file
rate_limiter
RateLimiter | None
Shared rate limiter instance used by all schedulers
snoozerScheduler
snoozerScheduler | None
High-frequency scheduler for live market data
clockworkScheduler
ClockworkScheduler | None
Fixed-interval scheduler for historical price data
shutdown_event
asyncio.Event
Event for coordinating graceful shutdown

Methods

load_and_validate_config()

Loads configuration from YAML file and validates feasibility.
def load_and_validate_config(self):
    """Load config and validate feasibility."""
Performs:
  • Configuration loading from YAML
  • Required field validation
  • Rate limit feasibility calculation
Raises:
  • SystemExit: If configuration is invalid or infeasible

validate_required_fields()

Validates that each tracking item has all required fields.
def validate_required_fields(self, items: list):
items
list
List of tracking items to validate
Required fields:
  • All items: market_hash_name, apiid, polling-interval-in-seconds, appid
  • histogram/activity: item_nameid (additional)
Valid apiids:
  • priceoverview
  • itemordershistogram
  • itemordersactivity
  • pricehistory
Raises:
  • SystemExit: If any required fields are missing or invalid

validate_config_feasibility()

Validates that configuration is feasible given rate limits.
def validate_config_feasibility(
    self, 
    rate_limit: int, 
    window_seconds: int, 
    items: list
):
rate_limit
int
Maximum requests per window
window_seconds
int
Time window in seconds
items
list
List of tracking items with their configurations
Calculates maximum requests per window assuming worst-case (all items synchronized). Real usage will typically be lower due to urgency-based scheduling spreading requests. Raises:
  • SystemExit: If calculated requests exceed rate limit

setup_schedulers()

Creates scheduler instances with shared rate limiter.
def setup_schedulers(self):
This method:
  1. Creates a single shared RateLimiter instance (critical for API compliance)
  2. Filters items by type (live vs. history)
  3. Initializes snoozerScheduler for live items (priceoverview, histogram, activity)
  4. Initializes ClockworkScheduler for pricehistory items

setup_signal_handlers()

Sets up signal handlers for graceful shutdown.
def setup_signal_handlers(self):
Registers handlers for:
  • SIGINT (Ctrl+C)
  • SIGTERM (kill command)

shutdown()

Handles graceful shutdown of all schedulers.
async def shutdown(self):
Sets the shutdown event, triggering all schedulers to stop gracefully.

run()

Main orchestrator loop. Runs all schedulers concurrently until shutdown signal.
async def run(self):
Algorithm:
  1. Load and validate configuration
  2. Setup schedulers with shared rate limiter
  3. Setup signal handlers for graceful shutdown
  4. Run all schedulers concurrently
  5. Wait for shutdown event or task failure
  6. Cancel remaining tasks and exit gracefully

Usage Example

import asyncio
from cerebro import Orchestrator

async def main():
    orchestrator = Orchestrator(config_path="config.yaml")
    await orchestrator.run()

if __name__ == "__main__":
    try:
        asyncio.run(main())
    except KeyboardInterrupt:
        print("\nKeyboard interrupt received. Exiting...")
    except Exception as e:
        print(f"\nFatal error: {e}")
        raise

Configuration Structure

The orchestrator expects a YAML configuration with the following structure:
LIMITS:
  REQUESTS: 15
  WINDOW_SECONDS: 60

TRACKING_ITEMS:
  - market_hash_name: "AK-47 | Redline (Field-Tested)"
    apiid: "priceoverview"
    appid: 730
    polling-interval-in-seconds: 30
    currency: 1
    country: "US"
    language: "english"
  
  - market_hash_name: "AWP | Asiimov (Field-Tested)"
    apiid: "itemordershistogram"
    appid: 730
    item_nameid: 176059193
    polling-interval-in-seconds: 60
730
int
Counter-Strike 2 (CS2)
570
int
Dota 2
440
int
Team Fortress 2
252490
int
Rust
753
int
Steam (trading cards, backgrounds, emoticons)